package model

import (
	"stock/global"
	"sync"

	"gorm.io/gorm"
)

type ProductModel struct {
	Base
}

type MallProduct struct {
	Id          uint   `json:"id" gorm:"<-:false; primaryKey;column:id;type:int(11)"`
	CategoryId  uint   `json:"category_id" gorm:"column:category_id;"`
	SupplierId  uint   `json:"supplier_id" gorm:"<-:false; column:supplier_id;"`
	SalesNum    uint   `json:"sales_num" gorm:"column:sales_num;"`
	CheckState  uint8  `json:"check_state" gorm:"column:check_state;"`
	IsUp        uint8  `json:"is_up" gorm:"column:is_up;"`
	IsDelete    uint8  `json:"is_delete" gorm:"column:is_delete;"`
	Sort        string `json:"sort" gorm:"column:sort;"`
	CreateTime  uint64 `json:"create_time" gorm:"column:create_time;"`
	UpdateTime  uint64 `json:"update_time" gorm:"column:update_time;"`
	Remark      string `json:"remark" gorm:"column:remark;"`
	Unit        string `json:"unit" gorm:"column:unit;"`
	CountryCode string `json:"country_code" gorm:"column:country_code;"`
	IsRecommend uint8  `json:"is_recommend" gorm:"column:is_recommend;"`
	Perfect     string `json:"perfect" gorm:"column:perfect;"`
	ProductLang string `json:"lang" gorm:"column:lang;"`
}

type RequestProduct struct {
	Id            uint
	CategoryId    uint
	CategoryIdArr []uint
	MerchantType  uint8
	MerchantId    uint
	CheckState    uint8
	IsUp          uint
	IsDelete      uint8
	IsRecommend   uint8
	CountryCode   string
	Perfect       []string
	IdArr         []uint
	Lang          string
}

type ResponseProduct struct {
	MallProduct
	ResponseLang
	ResponseFile
}

func (m *ProductModel) TabName() string {
	return global.CONF.Mysql.Prefix + "mall_product"
}

// 基础列表
func (m *ProductModel) BaseList(param RequestProduct, page global.PageSort) ([]MallProduct, int64) {

	where := &MallProduct{}
	if param.CategoryId != 0 {
		where.CategoryId = param.CategoryId
	}
	if param.MerchantId != 0 {
		where.SupplierId = param.MerchantId
	}
	if param.CheckState != 0 {
		where.CheckState = param.CheckState
	}
	if param.IsDelete != 0 {
		where.IsDelete = param.IsDelete
	}
	if param.IsRecommend != 0 {
		where.IsRecommend = param.IsRecommend
	}
	if param.CountryCode != "" {
		where.CountryCode = param.CountryCode
	}
	if param.Lang != "" {
		where.ProductLang = param.Lang
	}
	var product []MallProduct
	var tx *gorm.DB
	tx = global.DB.Debug().Where(where)
	if len(param.IdArr) > 0 && len(param.Perfect) > 0 && len(param.CategoryIdArr) > 0 {

		tx = tx.Where("id IN ?", param.IdArr).Where("perfect IN ?", param.Perfect).Where("category_id IN ?", param.CategoryIdArr)
	} else if len(param.IdArr) > 0 && len(param.Perfect) > 0 {

		tx = tx.Where("id IN ?", param.IdArr).Where("perfect IN ?", param.Perfect)
	} else if len(param.IdArr) > 0 && len(param.CategoryIdArr) > 0 {

		tx = tx.Where("id IN ?", param.IdArr).Where("category_id IN ?", param.CategoryIdArr)
	} else if len(param.Perfect) > 0 && len(param.CategoryIdArr) > 0 {

		tx = tx.Where("perfect IN ?", param.Perfect).Where("category_id IN ?", param.CategoryIdArr)
	} else if len(param.IdArr) > 0 {

		tx = tx.Where("id IN ?", param.IdArr)
	} else if len(param.CategoryIdArr) > 0 {

		tx = tx.Where("category_id IN ?", param.CategoryIdArr)
	} else if len(param.Perfect) > 0 {

		tx = tx.Where("perfect IN ?", param.Perfect)
	}
	tx.Order(page.Sortfield + " " + page.Sort).Offset(page.Page).Limit(page.Limit).Find(&product)
	var count int64
	global.DB.Debug().Model(where).Count(&count)
	return product, count
}

// 列表
func (m *ProductModel) List(param RequestProduct, page global.PageSort) ([]ResponseProduct, int64) {

	product, count := m.BaseList(param, page)
	productLen := len(product)
	var productArr []ResponseProduct
	if productLen > 0 {
		var productLangModel *LangModel = new(LangModel)
		var fileModel *FileModel = new(FileModel)

		var productWg sync.WaitGroup
		productWg.Add(productLen)
		for i := 0; i < productLen; i++ {
			go m.manyTabData(m.TabName(), product[i], productLangModel, fileModel, &productArr, &productWg)
		}
		productWg.Wait()
	}
	return productArr, count
}

// 基础详情
func (m *ProductModel) BaseDetail(param RequestProduct) {

}

// 详情
func (m *ProductModel) Detail(param RequestProduct, page global.PageSort) (ResponseProduct, error) {

	where := &MallProduct{}
	if param.CategoryId != 0 {
		where.CategoryId = param.CategoryId
	}
	if param.MerchantId != 0 {
		where.SupplierId = param.MerchantId
	}
	if param.CheckState != 0 {
		where.CheckState = param.CheckState
	}
	if param.IsDelete != 0 {
		where.IsDelete = param.IsDelete
	}
	if param.IsRecommend != 0 {
		where.IsRecommend = param.IsRecommend
	}
	if param.CountryCode != "" {
		where.CountryCode = param.CountryCode
	}
	if param.Lang != "" {
		where.ProductLang = param.Lang
	}
	var product MallProduct
	var fileModel *FileModel = new(FileModel)
	var tx *gorm.DB
	tx = global.DB.Debug().Where(where)
	if len(param.Perfect) > 0 {
		tx = tx.Where("perfect IN ?", param.Perfect)
	}
	tx.Order(page.Sortfield + " " + page.Sort).First(&product)
	var productArr []ResponseProduct
	if product.Id != 0 {
		var pLangModel *LangModel = new(LangModel)
		var productWg sync.WaitGroup
		productWg.Add(1)
		go m.manyTabData(m.TabName(), product, pLangModel, fileModel, &productArr, &productWg)
		productWg.Wait()
	}
	return productArr[0], nil
}

func (m *ProductModel) manyTabData(tabName string, prod MallProduct, pLangM *LangModel, fM *FileModel, productArr *[]ResponseProduct, wg *sync.WaitGroup) {

	var resProduct ResponseProduct
	//LANG
	var reLang ResponseLang
	reLang, _ = pLangM.List(RequestLang{
		TableName:    tabName,
		MerchantType: 1,
		MerchantId:   prod.SupplierId,
		TableId:      prod.Id,
		Field:        []string{"product_name", "description"},
		Lang:         global.LANG_COUNTRY.Lang,
	})
	resProduct.MerchantName = reLang.MerchantName
	resProduct.Description = reLang.Description
	resProduct.ProductName = reLang.ProductName
	resProduct.Name = reLang.ProductName
	//FILE
	var reFile ResponseFile
	reFile, _ = fM.List(RequestFile{
		MerchantType: 1,
		MerchantId:   prod.SupplierId,
		ProductId:    prod.Id,
		UsageTypd:    []uint{4, 7, 8, 10, 13},
	})
	resProduct.MainImg = reFile.MainImg
	*productArr = append(*productArr, resProduct)
	wg.Done()
}
